package xin.yangshuai.jvm01.classloader;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * MyClassLoader
 *
 * @author shuai
 * @date 2022/1/7
 */
public class MyClassLoader extends ClassLoader {

    private String rootPath;

    public MyClassLoader(String rootPath) {
        this.rootPath = rootPath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        String filePath = classToFilePath(name);

        byte[] bytes = getBytesFromPath(filePath);

        return defineClass(name, bytes, 0, bytes.length);
    }

    private byte[] getBytesFromPath(String filePath) {

        FileInputStream fis = null;
        ByteArrayOutputStream baos = null;

        try {
            fis = new FileInputStream(filePath);

            baos = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];

            int len;


            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;

    }

    private String classToFilePath(String name) {
        return rootPath + "\\" + name.replace(".", "\\") + ".class";
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {


        ArrayList<Object> list = new ArrayList<>();
        System.out.println(list.getClass().getClassLoader());

        MyClassLoader myClassLoader = new MyClassLoader("D:\\work\\IdeaProjects\\important-project\\jvm-01\\target\\classes");
        MyClassLoader myClassLoader1 = new MyClassLoader("D:\\work\\IdeaProjects\\important-project\\jvm-01\\target\\classes");
        Class<?> aClass = myClassLoader.findClass("xin.yangshuai.jvm01.classloader.A");
        Class<?> bClass = myClassLoader1.findClass("xin.yangshuai.jvm01.classloader.B");


        Constructor<?> bClassConstructor = bClass.getConstructor();
        Object b = bClassConstructor.newInstance();

//        Constructor<?> aClassConstructor = aClass.getConstructor(bClass);
//        Object a = aClassConstructor.newInstance(b);
//        System.out.println(a);

        //=======================================================================

//        Constructor<?> aClassConstructor1 = aClass.getConstructor(B.class);
//        Object o = aClassConstructor1.newInstance(new B());
//        System.out.println(o);

        Constructor<A> constructor = A.class.getConstructor(bClass);
        A a = constructor.newInstance(b);
        System.out.println(a);


    }
}
